package com.ews.onlineexchange.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.security.RolesAllowed;
import javax.enterprise.inject.Model;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Subquery;

import org.apache.commons.lang3.StringUtils;

import com.ews.onlineexchange.model.Bulletin;
import com.ews.onlineexchange.model.ChooseType;
import com.ews.onlineexchange.model.QualificationCert;
import com.ews.onlineexchange.model.QualificationLevel;
import com.ews.onlineexchange.model.QualificationTemplate;
import com.ews.onlineexchange.model.Sector;
import com.ews.onlineexchange.model.ServiceSupplier;
import com.ews.onlineexchange.model.Trade;

/**
 * 中介机构用户查询本用户尚未接受邀请的交易清单
 * 
 * @author admin
 *
 */
@Model
@RolesAllowed( value = "supplier" )
public class SupplierNotReceivedTradeList extends EntityQuery<Trade> {

	/**
	 * 
	 */
	private static final long	serialVersionUID	= 1L;

	@Inject
	UserService					userService;
	@Inject
	EntityManager				entityManager;

	public SupplierNotReceivedTradeList() {
		setMaxResults( EntityQuery.MAX_RESULTS_NORMAL );
	}

	@Inject
	CandidateSupplierSelector candidateSupplierSelector;

	@Override
	protected List<Predicate> getRestrictions( CriteriaQuery cq, CriteriaBuilder cb, Root<Trade> entity ) {
		ServiceSupplier loginedUser = (ServiceSupplier) userService.getLoginedUser();
		List<Predicate> restrictions = new ArrayList<Predicate>();
		restrictions.add( cb.isFalse( entity.<Boolean>get( "apply" ) ) );
		// Join<Trade, ServiceSupplier> supplier = entity.join("supplier");
		// restrictions.add(cb.notEqual(supplier.get("username"),
		// loginedUser.getUsername()));

		Join<Trade, Bulletin> bulletin = entity.join( "bulletin" );
		restrictions.add( cb.greaterThan( bulletin.<Date>get( "endingApplyTime" ), new Date() ) );// 当前时间小于截止时间
		restrictions.add( cb.notEqual( bulletin.get( "wayOfChoose" ), ChooseType.Manual ) );

		List<QualificationCert> certs = getCertsBySupplier( loginedUser.getId() );
		for ( QualificationCert cert : certs ) {
			List<QualificationTemplate> templates = cert.getQualificationTemplates();
			for ( QualificationTemplate template : templates ) {
				for ( Sector sector : template.getSectors() ) {
					Subquery<String> subQuery = cq.subquery( String.class );
					Root<Trade> validityId = subQuery.from( Trade.class );
					Join<Bulletin, QualificationTemplate> qualifationTemplate = validityId.join( "bulletin" )
							.join( "qualificationTemplate" );
					Join<QualificationTemplate, QualificationLevel> qualificationLevel = qualifationTemplate
							.join( "qualificationLevel" );
					Join<QualificationTemplate, Sector> joinSector = qualifationTemplate.join( "sectors" );
					Predicate preReq = cb.and( new Predicate[] { cb.equal( joinSector.get( "id" ), sector.getId() ),
							cb.equal( qualifationTemplate.get( "qualificationClass" ),
									template.getQualificationClass() ),
							cb.lessThanOrEqualTo( qualificationLevel.<Integer>get( "value" ),
									template.getQualificationLevel().getValue() ) } );
					subQuery.where( preReq );
					restrictions.add( cb.in( entity.get( "id" ) ).value( subQuery ) );

				}
			}
		}

		// Join<Bulletin,QualificationGroup> qualificationGroup =
		// bulletin.join("qualificationGroup");
		// List<ServiceSupplier> suppliers =
		// candidateSupplierSelector.getResultList((QualificationGroup)qualificationGroup);
		// boolean isBelong = false;
		// for (ServiceSupplier serviceSupplier : suppliers) {
		// if(loginedUser.getUsername().equals(serviceSupplier.getUsername())) {
		// isBelong = true;
		// }
		// }
		// if(!isBelong) {
		// restrictions.add(cb.equal(bulletin.get("id"), "0"));
		// }
		String projectName = (String) getParameterValues().get( "projectName" );
		if ( !StringUtils.isBlank( projectName ) )
			restrictions.add( cb.like( bulletin.get( "projectName" ), getStringRestriction( projectName ) ) );

		String serialNumber = (String) getParameterValues().get( "serialNumber" );
		if ( !StringUtils.isBlank( serialNumber ) )
			restrictions.add( cb.like( entity.get( "serialNumber" ), getStringRestriction( serialNumber ) ) );
		return restrictions;
	}

	private String SUPPLIER_CERTS_EQL = "SELECT qualificationCert" + " FROM QualificationCert qualificationCert"
			+ " WHERE qualificationCert.serviceSupplier.id = :serviceSupplierId";

	public List<QualificationCert> getCertsBySupplier( String serviceSupplierId ) {
		return entityManager.createQuery( SUPPLIER_CERTS_EQL ).setParameter( "serviceSupplierId", serviceSupplierId )
				.getResultList();
	}

	private String SUPPLIER_TEMPLATES_EQL = "SELECT qualificationTemplate"
			+ " FROM QualificationTemplate qualificationTemplate" + " WHERE qualificationTemplate.cert = :certId";

	public List<QualificationTemplate> getTemplates( String certId ) {
		return entityManager.createQuery( SUPPLIER_TEMPLATES_EQL ).setParameter( "certId", certId ).getResultList();
	}
}
